package com.wyz.saas.common.utils

import android.graphics.BitmapFactory
import com.atom.module.mvvm.base.AbstractApplication
import com.bumptech.glide.Glide
import java.io.File
import com.bumptech.glide.request.target.Target

object PicturesCompressor  {
    fun compressImage(
        srcPath: String,
        savePath: String,
        targetSize: Long
    ): Boolean {
        return compressImage(srcPath, savePath, targetSize, 75, 1280, 1280 * 6, null, null, true)
    }

    private fun loadWithGlideCache(path: String): File? {
        val tmp: File
        return try {
            tmp = Glide.with(AbstractApplication.getInstance())
                .load(path)
                .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
                .get()
            tmp
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    /**
     * 压缩图片
     *
     * @param srcPath     原图地址
     * @param savePath    存储地址
     * @param maxSize     最大文件地址byte
     * @param minQuality  最小质量
     * @param maxWidth    最大宽度
     * @param maxHeight   最大高度
     * @param byteStorage 用于批量压缩时的buffer，不必要为null，
     * 需要时，推荐 {[BitmapUtil.DEFAULT_BUFFER_SIZE]}
     * @param options     批量压缩时复用参数，可调用 {[BitmapUtil.createOptions]} 得到
     * @param exactDecode 是否精确解码， TRUE： 在4.4及其以上机器中能更节约内存
     * @return 是否压缩成功
     */
    fun compressImage(
        srcPath: String,
        savePath: String,
        maxSize: Long,
        minQuality: Int,
        maxWidth: Int,
        maxHeight: Int,
        byteStorage: ByteArray?,
        options: BitmapFactory.Options?,
        exactDecode: Boolean
    ): Boolean {
        var loadWithGlide = false
        // build source file
        val inTmp = File(srcPath)
        val sourceFile: File
        if (inTmp.exists()) {
            sourceFile = inTmp
        } else {
            val tmp: File = loadWithGlideCache(srcPath) ?: return false
            sourceFile = tmp
            loadWithGlide = true
        }

        // build save file
        val saveFile = File(savePath)
        val saveDir: File = saveFile.parentFile
        if (!saveDir.exists()) {
            if (!saveDir.mkdirs()) return false
        }

        // End clear the out file data
        if (saveFile.exists()) {
            if (!saveFile.delete()) return false
        }

        // if the in file size <= maxSize, we can copy to savePath
        if (sourceFile.length() <= maxSize && confirmImage(sourceFile, options)) {
            return StreamUtil.copy(sourceFile, saveFile)
        }
        val realCacheFile: File?
        if (loadWithGlide) {
            realCacheFile = sourceFile
        } else {
            realCacheFile = loadWithGlideCache(sourceFile.absolutePath)
            if (realCacheFile == null) return false
        }

        // Doing
        val tempFile = BitmapUtil.compressImage(
            realCacheFile, maxSize, minQuality, maxWidth,
            maxHeight, byteStorage, options, exactDecode
        )

        // Rename to out file
        return tempFile != null && StreamUtil.copy(tempFile, saveFile) && tempFile.delete()
    }

    fun confirmImage(file: File, optsFinal: BitmapFactory.Options?): Boolean {
        var opts = optsFinal
        if (opts == null) opts = BitmapUtil.createOptions()
        opts.inJustDecodeBounds = true
        BitmapFactory.decodeFile(file.absolutePath, opts)
        val mimeType = opts.outMimeType.toLowerCase()
        return mimeType.contains("jpeg") || mimeType.contains("png") || mimeType.contains("gif")
    }
}